# coding: utf8
import importlib
import random
import string

import subprocess


import ansible
from ansible.cli.playbook import PlaybookCLI
from ansibleWorker.ansibleworker import *
from public.models import *
import logging, datetime
import paramiko
from onecup.settings import BASE_DIR,REMOTE_PLAYBOOK_ROLE_PATH,REMOTE_PLAYBOOK_PATH,REMOTE_SOFTWARE_PATH, DES_SECRET_KEY
from ansible.cli.galaxy import GalaxyCLI as mycli
from public.viewFunc.util import des_decrypt
# from ansible.cli.playbook import PlaybookCLI

logger = logging.getLogger('ansible.ui')


# ansible 执行接口, 传如香港参赛
class AnsibleOpt:
    @staticmethod
    def scpFileToRemoteNode(user, ip, password, localsource, remotedest, port=22):
        scp_cmd_base = r""" expect -c " set timeout 10 ; spawn scp -P {port} -r {localsource} {username}@{host}:{remotedest} ; expect *assword* {{{{ send {password}\r }}}} ; expect *\r ; expect \r ; expect eof " """.format(
            username=user, password=password, host=ip, localsource=localsource, remotedest=remotedest, port=port)
        scp_cmd = scp_cmd_base.format(localsource=localsource)
        #print("execute scp_cmd: ", scp_cmd)
        p = subprocess.Popen(scp_cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
        p.communicate()
        result = os.system(scp_cmd)
        if result == 0:
            #print('修改权限')
            ssh = paramiko.SSHClient()
            ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
            ssh.connect(hostname=ip, port=22, username=user, password=password)
            ssh.exec_command("chmod -R 777 %s " % remotedest)
            ssh.close()
        return result

    @staticmethod
    def ansible_roles_trans(roles, sys_ip, sys_user, sys_pass):
        sys_ip = sys_ip
        playfile = os.path.join(BASE_DIR, 'ansibleWorker/playbooks/roles', roles)
        playfile += '/'
        remotefile = REMOTE_PLAYBOOK_ROLE_PATH
        print(playfile)
        print('开始传输文件')
        result = AnsibleOpt.scpFileToRemoteNode(sys_user, str(sys_ip), sys_pass, str(playfile), str(remotefile), 22)
        print('文件传输完成')
        return result

    @staticmethod
    def software_trans(software, sys_ip, sys_user, sys_pass):
        sys_ip = sys_ip
        softwares = os.path.join(BASE_DIR, 'ansibleWorker/software', software)
        softwares += '/'
        remotefile = REMOTE_SOFTWARE_PATH
        print(softwares)
        print('开始传输文件')
        result = AnsibleOpt.scpFileToRemoteNode(sys_user, str(sys_ip), sys_pass, str(softwares), str(remotefile), 22)
        print('文件传输完成')
        return result

    @staticmethod
    def ansible_playbook(systemname, playbook, user=None, inventory=any, extra_vars={}, **kw):
        tid = "AnsibleApiPlaybook-%s-%s" % (''.join(random.sample(string.ascii_letters + string.digits, 8)),
                                            datetime.datetime.now().strftime("%Y%m%d-%H%M%S"))
        taskname = SystemsLists.objects.get(systemname=systemname).task
        remoteip = SystemsLists.objects.get(systemname=systemname).control_host
        agent_user = SystemsLists.objects.get(systemname=systemname).agent_user
        agent_pass = str(des_decrypt(DES_SECRET_KEY, SystemsLists.objects.get(systemname=systemname).agent_pass), 'utf-8')
        playfile = os.path.join(BASE_DIR, 'ansibleWorker/playbooks', playbook)
        remotefile = REMOTE_PLAYBOOK_PATH + playbook
        AnsibleOpt.scpFileToRemoteNode(agent_user, str(remoteip), agent_pass, str(playfile), str(remotefile), 22)
        print("添加Ansible-Playbook执行；(%s - %s - %s - %s)" % (playbook, taskname, extra_vars, kw))
        inventory = str(inventory)
        celeryTask = execplaybooks.apply_async((tid, playbook, inventory, extra_vars), queue=taskname)
        label = kw.get('label', '')
        at = AnsibleTasks(AnsibleID=tid, CeleryID=celeryTask.task_id, SystemName=systemname, TaskUser=user,
                          ExtraVars=extra_vars, playbook=playbook, TaskName=taskname, Label=label)
        at.save()
        return {"id": at.pk, "playbook": playbook, "extra_vars": extra_vars, "tid": tid,
                "celeryTask": celeryTask.task_id, "taskName": taskname}

    @staticmethod
    def ansible_roles(ansiblerole):
        try:
            playbook_path = os.path.join(BASE_DIR, 'ansibleWorker/playbooks/')
            args = ['manage.py', 'install', str(ansiblerole), '-p', playbook_path, '--force']
            mycli(args).run()
            print(args)
            msg = '下载成功'
        except:
            msg = '下载失败'
        return msg

    @staticmethod
    def playbook_check(playbooks):
        playbooks = os.path.join(BASE_DIR, 'ansibleWorker/playbooks/', str(playbooks))
        print(playbooks)
        aa = 'ansible-playbook --syntax-check ' + playbooks + ''
        p = subprocess.Popen(aa, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
        p1 = "".join(str(p.stderr.readlines()))
        if p1:
            errorsupper = p1.find('ERROR')
            errorslower = p1.find('error')
        else:
            errorsupper = -1
            errorslower = -1
        if errorsupper == -1 and errorslower == -1:
            result = '语法正常'
        else:
            p1 = p1.replace('b\'', '').replace('b\"', '').replace('[', '').replace(']', '').replace('\\n', '\\').replace(
                '\',', '').replace('\",', '')
            result = ''
            for i in p1:
                if i == '\\':
                    result += '\n'
                else:
                    result += i
            p.communicate()
            print(result)
        return result



